<?php

declare(strict_types=1);

namespace App\Order\Task;

use App\Common\Constants\Stakeholder;
use App\Order\Model\FreeOrderRefund;
use App\Order\Model\OrderModel;
use App\Order\Service\OrderRefundService;
use Hyperf\Crontab\Annotation\Crontab;
use Hyperf\DbConnection\Db;
use Hyperf\Utils\ApplicationContext;

/**
 * 退款给免单订单的发起人
 *
 * @Crontab(name="RefundFreeOrder", rule="*\/5 * * * *", callback="task")
 * Class RefundFreeOrder
 * @package App\Order\Task
 */
class RefundFreeOrder
{
    public function task()
    {
        $container = ApplicationContext::getContainer();
        $refundService = $container->get(OrderRefundService::class);
        $send = $container->get(UpdateFreeStatus::class);
        $where = [
            'is_pay'     => 1,
            'order_type' => Stakeholder::ORDER_TYPE_FREE,
            'is_freed'   => 2,
        ];
        $beforeTwoDay = date('Y-m-d H:i:s', strtotime('-2 day'));
        $model = OrderModel::where($where)->where('pay_at', '<', $beforeTwoDay)->where('free_success_time', '<', $beforeTwoDay);
        $model->chunk(1000, function ($orders) use ($refundService, $send) {
            foreach ($orders as $order) {
                $result = $refundService->shopRefund($order->order_no, Stakeholder::WHOLE_REFUND);
                if ($result['code'] != 1) {
                    continue;
                }
                FreeOrderRefund::create([
                    'order_no'     => $order->order_no,
                    'refund_no'    => $this->createRefundNo(),
                    'refund_money' => $order->total_price,
                    'result'       => serialize([
                        'order'         => $order->toArray(),
                        'refund_result' => $result
                    ])
                ]);
                OrderModel::where('order_no', $order->order_no)->update(['is_freed' => 4]);
                $send->sendRefundSuccessMsgForFree($order->order_no);
            }
        });
    }

    /**
     * 创建退款单号
     *
     * @return string
     * @author mengchenchen
     */
    public function createRefundNo()
    {
        return "XPT" . (int)(microtime(true) * 1000) . mt_rand(100000, 999999);
    }
}
